package com.spsoft.core.utils;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.format.FastDateFormat;
import cn.hutool.core.util.StrUtil;
import com.spsoft.core.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class DateUtils extends cn.hutool.core.date.DatePattern {


    public static final DateTimeFormatter DF_NORM_DATE_PATTERN =
            DateTimeFormatter.ofPattern(NORM_DATE_PATTERN);

    public static final DateTimeFormatter DF_NORM_MONTH_PATTERN =
            DateTimeFormatter.ofPattern("yyyy-MM");

    /**
     * 月份日期格式：yyyy-MM
     */
    public static final String NORM_MONTH_DATE_PATTERN = "yyyy-MM";

    /**
     * 日期格式一：MM/dd/y
     */
    public static final String NORM_DAY_DATE_PATTERN_1 = "MM/dd/yy";

    /**
     * 日期格式一：MM/dd/y
     */
    public static final String NORM_DAY_DATE_PATTERN_2 = "yyyy.MM.dd";

    /**
     * 判断参数的格式是否为“yyyyMMdd”格式的合法日期字符串
     */
    public static boolean isValidDate(String str) {
        try {
            if (str != null && !str.equals("")) {
                if (str.length() == 8) {
                    // 闰年标志
                    boolean isLeapYear = false;
                    String year = str.substring(0, 4);
                    String month = str.substring(4, 6);
                    String day = str.substring(6, 8);
                    int vYear = Integer.parseInt(year);
                    // 判断年份是否合法
                    if (vYear < 1900 || vYear > 2200) {
                        return false;
                    }
                    // 判断是否为闰年
                    if (vYear % 4 == 0 && vYear % 100 != 0 || vYear % 400 == 0) {
                        isLeapYear = true;
                    }
                    // 判断月份
                    // 1.判断月份
                    if (month.startsWith("0")) {
                        String units4Month = month.substring(1, 2);
                        int vUnits4Month = Integer.parseInt(units4Month);
                        if (vUnits4Month == 0) {
                            return false;
                        }
                        if (vUnits4Month == 2) {
                            // 获取2月的天数
                            int vDays4February = Integer.parseInt(day);
                            if (isLeapYear) {
                                if (vDays4February > 29) {
                                    return false;
                                }
                            } else {
                                if (vDays4February > 28) {
                                    return false;
                                }
                            }
                        }
                    } else {
                        // 2.判断非0打头的月份是否合法
                        int vMonth = Integer.parseInt(month);
                        if (vMonth != 10 && vMonth != 11 && vMonth != 12) {
                            return false;
                        }
                    }
                    // 判断日期
                    // 1.判断日期
                    if (day.startsWith("0")) {
                        String units4Day = day.substring(1, 2);
                        int vUnits4Day = Integer.parseInt(units4Day);
                        return vUnits4Day != 0;
                    } else {
                        // 2.判断非0打头的日期是否合法
                        int vDay = Integer.parseInt(day);
                        return vDay >= 10 && vDay <= 31;
                    }
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 判断日期格式:yyyy-mm-dd
     *
     * @param sDate
     * @return
     */
    public static boolean isValidDate2(String sDate) {
        String datePattern1 = "\\d{4}-\\d{2}-\\d{2}";
        String datePattern2 =
                "^((\\d{2}(([02468][048])|([13579][26]))"
                        + "[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|"
                        + "(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?"
                        + "((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?("
                        + "(((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?"
                        + "((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))";
        if ((sDate != null)) {
            Pattern pattern = Pattern.compile(datePattern1);
            Matcher match = pattern.matcher(sDate);
            if (match.matches()) {
                pattern = Pattern.compile(datePattern2);
                match = pattern.matcher(sDate);
                return match.matches();
            } else {
                return false;
            }
        }
        return false;
    }

    /**
     * 将localDateTime转换为Date类型
     *
     * @param localDateTime
     * @return
     */
    public static Date convertLocalTimeToDate(LocalDateTime localDateTime) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        Date date = Date.from(zdt.toInstant());
        return date;
    }

    /**
     * 将llocalDate转换为Date类型
     *
     * @param localDate
     * @return
     */
    public static Date convertLocalTimeToDate(LocalDate localDate) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDate.atStartOfDay(zoneId);
        Date date = Date.from(zdt.toInstant());
        return date;
    }

    public static String getSysTime() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
        return df.format(new Date());// new Date()为获取当前系统时间
    }

    // int型时间戳改成日期类型
    public static String stampToDate(String s) {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long lt = new Long(s);
        lt = lt * 1000L;
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }

    public static String getSysYear() {
        Calendar date = Calendar.getInstance();
        return Convert.toStr(date.get(Calendar.YEAR));

    }

    public static String getYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return Convert.toStr(calendar.get(Calendar.YEAR));
    }

    /**
     * 得到当前月的第一天
     *
     * @return
     */
    public static Date getTolMonthFirstDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 得到当前月的最后一天
     *
     * @return
     */
    public static Date getTolMonthLastDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    public static String getFirstDayDateOfMonth(final Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        final int last = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, last);
        return DateUtils.formatDate(cal.getTime(), "yyyy-MM-dd");
    }

    public static String getLastDayOfMonth(final Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        final int last = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, last);
        return DateUtils.formatDate(cal.getTime(), "yyyy-MM-dd");
    }

    /**
     * 获取monthNumber个月后的日期
     *
     * @param date
     * @param monthNumber
     * @return
     */
    public static Date getAfterMonthDate(Date date, int monthNumber) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, monthNumber);
        return calendar.getTime();
    }

    /**
     * 根据 pattern规则 解析获取对应日期 Date类型
     *
     * @param dateStr
     * @param pattern
     * @return
     */
    public static Date parseDate(String dateStr, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.parse(dateStr);
        } catch (Exception e) {
            //e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据 pattern规则 解析获取对应日期 Date类型
     *
     * @param dateStr
     * @param pattern
     * @return
     */
    public static Date parseDate2(String dateStr, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.parse(dateStr);
        } catch (Exception e) {
            //e.printStackTrace();
            return new Date();
        }
    }

    /**
     * 根据 pattern规则 解析获取对应日期 String类型
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    /*
     * 获取年月数据
     */
    public static int getSysYearMonth() {
        SimpleDateFormat dform = new SimpleDateFormat("yyyyMM");// 设置日期格式
        String dateformat = dform.format(new Date());
        return Integer.parseInt(dateformat);
    }

    /*
     * 获取年月数据
     */
    public static String getSysYearMonth1() {
        SimpleDateFormat dform = new SimpleDateFormat("yyyy-MM");// 设置日期格式
        String dateformat = dform.format(new Date());
        return dateformat;
    }

    /**
     * 获取当前年第一天日期
     *
     * @param
     * @return Date
     */
    public static Date getCurrYearFirst() {
        Calendar date = Calendar.getInstance();
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, date.get(Calendar.YEAR));
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 获取指定时间为当前时间的几月后
     *
     * @param
     * @return Date
     */
    public static int indexOfCalendarForMonth(Date date) {

        if (date == null || "".equals(date)) {
            return 0;
        }

        Calendar from = Calendar.getInstance();
        from.setTime(new Date());
        Calendar to = Calendar.getInstance();
        to.setTime(date);

        int fromYear = from.get(Calendar.YEAR);
        int fromMonth = from.get(Calendar.MONTH);
        int fromDay = from.get(Calendar.DAY_OF_MONTH);

        int toYear = to.get(Calendar.YEAR);
        int toMonth = to.get(Calendar.MONTH);
        int toDay = to.get(Calendar.DAY_OF_MONTH);
        int year = toYear - fromYear;
        int month = toMonth - fromMonth;
        int day = toDay - fromDay;

        return year * 12 + month;
    }


    /**
     * 根据生日年月获取年龄周岁
     *
     * @param
     * @return Date
     */
    public static int getAgeByBirthdayMonth(Date birthday) {
        Calendar from = Calendar.getInstance();
        from.setTime(birthday);
        Calendar to = Calendar.getInstance();
        to.setTime(new Date());

        int fromYear = from.get(Calendar.YEAR);
        int fromMonth = from.get(Calendar.MONTH);
        int fromDay = from.get(Calendar.DAY_OF_MONTH);

        int toYear = to.get(Calendar.YEAR);
        int toMonth = to.get(Calendar.MONTH);
        int toDay = to.get(Calendar.DAY_OF_MONTH);
        int year = toYear - fromYear;
        int month = toMonth - fromMonth;
        int day = toDay - fromDay;
        int age = (year * 12 + month) / 12;
        return age;
    }

    /**
     * 获取当前年最后一天日期
     *
     * @param
     * @return Date
     */
    public static Date getCurrYearLast() {
        Calendar date = Calendar.getInstance();
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, date.get(Calendar.YEAR));
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();

        return currYearLast;
    }

    /**
     * 获得两个日期之间的所有月份
     *
     * @param minDate
     * @param maxDate
     * @return
     * @throws ParseException
     */
    public static List<String> getMonthBetween(String minDate, String maxDate) {
        List<String> result = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        try {
            min.setTime(sdf.parse(minDate));
            min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

            max.setTime(sdf.parse(maxDate));
            max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
        } catch (Exception e) {
            //e.printStackTrace();
            return result;
        }

        Calendar curr = min;
        while (curr.before(max)) {
            result.add(sdf.format(curr.getTime()));
            curr.add(Calendar.MONTH, 1);
        }

        return result;
    }


    /**
     * 获得两个日期之间的所有年份
     * @param startDateStr
     * @param endDateStr
     * @return
     */
    public static List<String> getYearsBetweenDates(String startDateStr, String endDateStr) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate startDate = LocalDate.parse(startDateStr, formatter);
        LocalDate endDate = LocalDate.parse(endDateStr, formatter);

        List<String> years = new ArrayList<>();
        for (int year = startDate.getYear(); year <= endDate.getYear(); year++) {
            years.add(Integer.toString(year));
        }
        return years;
    }


    /**
     * 获得两个日期之间的所有日
     * @param startDateStr
     * @param endDateStr
     * @return
     */
    public static List<String> getDaysBetweenDates(String startDateStr, String endDateStr) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate startDate = LocalDate.parse(startDateStr, formatter);
        LocalDate endDate = LocalDate.parse(endDateStr, formatter);

        List<String> days = new ArrayList<>();
        for (LocalDate date = startDate; date.isBefore(endDate.plusDays(1)); date = date.plusDays(1)) {
            days.add(date.format(formatter));
        }

        return days;
    }


    /**
     *  填充指定时间段内的所有日期  填充后格式:yyyy-MM-dd
     */
    public static List<String> fillsAllDates(String startTimeStr,String endTimeStr){
//          先列出所有的日期,然后从list里面拿出来后进行删除操作,然后再添加到list即可
        FastDateFormat fstDD = FastDateFormat.getInstance("yyyy-MM-dd");
        FastDateFormat fstMM = FastDateFormat.getInstance("yyyy-MM");
//        获得两个日期之间的所有月份
        List<String> monthBetween = getMonthBetween(startTimeStr, endTimeStr);
        List<String> dateList = new ArrayList<>();
        try {
        Date startTime = fstDD.parse(startTimeStr);
        Date endTime = fstDD.parse(endTimeStr);
//      代表开始时间及结束时间不是同一个月
        if(monthBetween.size() >= 2){
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(startTime);
                int startTimeDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);//天数
                int startTimeYear = calendar.get(Calendar.YEAR);//年份
                int startTimeMonth = calendar.get(Calendar.MONTH) + 1;//月份
                String startTimeMonthStr = Integer.toString(startTimeMonth);
            // 10月份之前,月份都是1月2月等..不是01月02月,需要自行添加0在前面,calendar坑点,读取的月份永远比真实月份少一个月....我服了
                if (startTimeMonth < 10) {
                    startTimeMonthStr = "0" + startTimeMonth;
                }
                int startTimeMaxDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
//            不相等说明开始时间的天数不是当月的最后一天
                if (startTimeDayOfMonth != startTimeMaxDayOfMonth) {
//                小于10的时候,添加日期时需要在天数前加 '0'
//                    10之前的天数都添加上
                    while (startTimeDayOfMonth < 10) {
                        dateList.add(startTimeYear + "-" + startTimeMonthStr + "-" + "0" + startTimeDayOfMonth);
                        startTimeDayOfMonth+=1;
                    }
                    while (startTimeDayOfMonth <= startTimeMaxDayOfMonth) {
                        dateList.add(startTimeYear + "-" + startTimeMonthStr + "-" + startTimeDayOfMonth);
                        startTimeDayOfMonth+=1;
                    }
                }else{
                    dateList.add(startTimeStr);
                }
                calendar.clear();
                calendar.setTime(endTime);
                int endTimeDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);//天数
                int endTimeYear = calendar.get(Calendar.YEAR);//年份
                int endTimeMonth = calendar.get(Calendar.MONTH) + 1;//月份
                String endTimeMonthStr = Integer.toString(endTimeMonth);
    //          10月份之前,月份都是1月2月等..不是01月02月,需要自行添加0在前面
                if (endTimeMonth < 10) {
                    endTimeMonthStr = "0" + endTimeMonth;
                }
                    for (int i = 1; i <= endTimeDayOfMonth; i++) {
                        if (i < 10) {
                            dateList.add(endTimeYear + "-" + endTimeMonthStr + "-" + "0" + i);
                        }else{
                            dateList.add(endTimeYear + "-" + endTimeMonthStr + "-" + i);
                        }
                    }

//                把开始时间及结束时间的那个月份数据添加到list,再处理中间间隔的所有月份!
            if (monthBetween.size() >= 3) { //≥3说明不是同月且不是相邻的两个月!
                monthBetween.remove(0);//删除开始时间
                monthBetween.remove(monthBetween.size() - 1);//删除结束时间
                for (String date:monthBetween
                     ) {
                    calendar.clear();
                    calendar.setTime(fstMM.parse(date));
                    int maxDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
                    int year = calendar.get(Calendar.YEAR);//年份
                    int month = calendar.get(Calendar.MONTH) + 1;//月份
                    if (month < 10) {
                        for (int i = 1; i < 10; i++) {
                            dateList.add(year + "-" + "0" + month + "-" + "0" + i);
                        }
                        for (int i = 10; i <= maxDayOfMonth; i++) {
                            dateList.add(year + "-" + "0" + month + "-" + i);
                        }
                    }else{
                        for (int i = 1; i < 10; i++) {
                            dateList.add(year + "-" + month + "-" + "0" + i);
                        }
                        for (int i = 10; i <= maxDayOfMonth; i++) {
                            dateList.add(year + "-" + month + "-" + i);
                        }
                    }
                }
            }
        }else if(monthBetween.size() == 1){//同月处理
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(endTime);
            int year = calendar.get(Calendar.YEAR);//年份
            int month = calendar.get(Calendar.MONTH) + 1;//月份
            String monthStr = Integer.toString(month);
            if (month < 10) {
                monthStr = "0" + month;
            }
            int endTimeDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);//结束时间的天数
            calendar.clear();
            calendar.setTime(startTime);
            int startTimeDayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);//开始时间的天数
            if(endTimeDayOfMonth - startTimeDayOfMonth > 1){ //不能是同一天也不能是相邻的日期
                for (int i = startTimeDayOfMonth; i <= endTimeDayOfMonth ; i++) {
                    if (startTimeDayOfMonth < 10) {
                        dateList.add(year + "-" + monthStr + "-" + "0" + i);
                    }else{
                        dateList.add(year + "-" + monthStr + "-" + i);
                    }
                }
            }else if(endTimeDayOfMonth - startTimeDayOfMonth == 1){//相邻的话就把开始和结束日期放进去就可
                dateList.add(startTimeStr);
                dateList.add(endTimeStr);
            }else{//同一天就只需要一个日期了
                dateList.add(startTimeStr);
            }
        }
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return dateList;
    }
    /**
     * 根据yyyy-MM获取上个月的日期 yyyy-MM格式
     *
     * @param yearMonths
     * @return
     */
    public static String getLastMonth(String yearMonths) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月

        Calendar cal = Calendar.getInstance();

        try {
            cal.setTime(sdf.parse(yearMonths));
        } catch (ParseException e) {
            //e.printStackTrace();
            return "";
        }
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), -1);

        return sdf.format(cal.getTime());
    }

    /**
     * 把开始时间和结束时间转换成Date类型,并把结束时间设置为当天最大时间23:59:59,以此方便查询  --不然会查00:00:00,查不出当天数据
     * @param startTimeStr 开始时间字符串 yyyy-MM-dd
     * @param endTimeStr    结束时间字符串 yyyy-MM-dd
     * @param startTime 调用本方法时声明一个Date传进来以此把字符串转化后赋值
     * @param endTime   调用本方法时声明一个Date传进来以此把字符串转化后赋值
     */
    public static Map<String,Date> setMaxTimeByStr(String startTimeStr,String endTimeStr,Date startTime,Date endTime){
        FastDateFormat fst = FastDateFormat.getInstance("yyyy-MM-dd");
        try {
            startTime = fst.parse(startTimeStr);
            endTime = fst.parse(endTimeStr);
        } catch (ParseException e) {
            throw new BaseException("日期转换异常");
        }
//      需要把时分秒设置到 23:59:59 这样才能覆盖到结束日期的这一天的数据,不然时间默认是00:00:00
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(endTime.getTime()), ZoneId.systemDefault());
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        endTime = Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
        Map<String, Date> map = new HashMap<>();
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        return map;
    }



    /**
     * 判断参数的格式是否为“yyyyMM”格式的合法日期字符串
     */
    public static boolean isValidDate3(String str) {
        try {
            if (str != null && !str.equals("")) {
                if (str.length() == 6) {
                    // 闰年标志
                    String year = str.substring(0, 4);
                    String month = str.substring(4, 6);
                    int vYear = Integer.parseInt(year);
                    // 判断年份是否合法
                    if (vYear < 1900 || vYear > 2200) {
                        return false;
                    }

                    // 判断月份
                    // 1.判断月份
                    if (month.startsWith("0")) {
                        String units4Month = month.substring(1, 2);
                        int vUnits4Month = Integer.parseInt(units4Month);
                        if (vUnits4Month == 0) {
                            return false;
                        }
                    } else {
                        // 2.判断非0打头的月份是否合法
                        int vMonth = Integer.parseInt(month);
                        if (vMonth != 10 && vMonth != 11 && vMonth != 12) {
                            return false;
                        }
                    }

                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 日期转换  yyyyMMdd --> yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String convDate(String date) {
        //日期转换  20201001 --> 2020-10-01
        if (DateUtils.isValidDate(date)) {
            StringBuilder sb = new StringBuilder(date);
            sb.insert(6, "-");
            sb.insert(4, "-");
            date = sb.toString();
        }
        return date;
    }

    /**
     * 日期转换  yyyy年MM月dd日 --> yyyyMMdd
     *
     */
    public static String convDate2(String date) {
        if (StrUtil.isBlank(date)) {
            return "";
        }
        //日期转换  2020年10月01日 --> 2020-10-01
        return date.replace("年", "").replace("月", "").replace("日","");
    }

    /**
     * 日期转换   yyyy-MM-dd --> yyyyMMdd
     *
     * @param date
     * @return
     */
    public static String convDate1(String date) {
        //日期转换  2020-10-01->20201001
        if (StringUtils.isNotBlank(date)) {
            date = date.replace("-", "");
        }
        return date;
    }

    public static String convVoucherDate(String date) {
        //日期转换  202010 --> 2020-10
        StringBuilder sb = new StringBuilder(date);
        sb.insert(4, "-");
        date = sb.toString();

        return date;
    }

    /**
     * int类型时间戳 ->  yyyy-MM-dd
     *
     * @param dateInt
     * @return
     */
    public static String intToDate(Integer dateInt) {
        if (null == dateInt) {
            return null;
        }
        Date date = new Date((long) dateInt * 1000);
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return localDateTime.format(formatter);
    }


    /**
     * Date类型 ->  2022年01月12日
     *
     * @param date
     * @return
     */
    public static String getDateToStr(Date date) {
        if (null == date) {
            return null;
        }
        LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        return localDateTime.format(formatter);
    }

    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2)   //同一年
        {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)    //闰年
                {
                    timeDistance += 366;
                } else    //不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else    //不同年
        {
            return day2 - day1;
        }
    }

    /**
     * 根据 pattern规则 解析获取对应日期 Date类型
     *
     * @param dateStr
     * @param pattern
     * @return
     */
    public static Date fastParseDate(String dateStr, String pattern) {
        if (StrUtil.isBlank(dateStr)) {
            return null;
        }
        try {
            return FastDateFormat.getInstance(pattern).parse(dateStr);
        } catch (ParseException e) {
            log.error(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
        if (nowTime.getTime() == beginTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

}
